package com.ibm.crl.sb.thread.typicalexam.procon;

import java.util.ArrayList;
import java.util.List;

/**
 * java多线程一般都会讲消费者-生产者模型
 * 
 * 生产者与消费者模型中，要保证以下几点：
 * 
 * 1 同一时间内只能有一个生产者生产
 * 
 * 2 同一时间内只能有一个消费者消费
 * 
 * 3 生产者生产的同时消费者不能消费
 * 
 * 4消息队列满时生产者不能继续生产
 * 
 * 5 消息队列空时消费者不能继续消费
 * 
 * @author shangbin
 * 
 */
public class Producer_Consumer_Test {
	public static void main(String[] args) {

		Queue Q = new Queue();

		Producer wQ1 = new Producer(Q);
		Producer wQ2 = new Producer(Q);
		Producer wQ3 = new Producer(Q);
		// Producer wQ4 = new Producer(Q);
		// Producer wQ5 = new Producer(Q);

		Consumer rQ1 = new Consumer(Q);
		Consumer rQ2 = new Consumer(Q);
		Consumer rQ3 = new Consumer(Q);
		Consumer rQ4 = new Consumer(Q);
		Consumer rQ5 = new Consumer(Q);

		// Thread threadWQ1 = new Thread(wQ1, "thread-wQ1");
		// Thread threadWQ2 = new Thread(wQ2, "thread-wQ2");
		//
		// Thread threadRQ1 = new Thread(rQ1, "thread-rQ1");
		// Thread threadRQ2 = new Thread(rQ2, "thread-rQ2");
		// Thread threadRQ3 = new Thread(rQ3, "thread-rQ3");

		wQ1.start();
		wQ2.start();
		wQ3.start();
		// wQ4.start();
		// wQ5.start();

		rQ1.start();
		rQ2.start();
		rQ3.start();
		rQ4.start();
		rQ5.start();
	}
}

/**
 * 队列
 * 
 * @author DELL
 * 
 */
class Queue {
	List<Message> queue = new ArrayList<Message>();

	/** 队列中message对象的最大值,默认为5 */
	int maxMessageNum = 5;

	// 生产产品
	public synchronized void produce(Message message) {
		while (queue.size() == maxMessageNum) {
			System.out.println(Thread.currentThread().getName()
					+ "  队列满！等待中。。。");
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		queue.add(message);
		System.out.println(Thread.currentThread().getName() + "正在生产"
				+ message.getContent() + "。。。  ,当前个数:" + getCount());
		this.notifyAll();

	}

	// 消费产品
	public synchronized void consume() {
		while (queue.size() == 0) {
			System.out.println(Thread.currentThread().getName()
					+ "  队列空！等待中。。。");
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		Message message = queue.get(0);
		queue.remove(0);
		System.out.println(Thread.currentThread().getName() + "正在消费"
				+ message.getContent() + "。。。 ,当前个数: " + getCount());
		this.notifyAll();

	}

	public synchronized int getCount() {
		return queue.size();
	}
}

/**
 * 生产者
 * 
 * @author DELL
 * 
 */
class Producer extends Thread {

	private Queue queue;

	Producer(Queue queue) {
		this.queue = queue;
	}

	public void run() {

		while (true) {
			Message message = new Message();
			message.setId(++Message.id);
			message.setContent("food" + Message.id);
			queue.produce(message);
//			try {
//				sleep(1000);
//			} catch (Exception e) {
//			}
		}

	}
}

/**
 * 消费者
 * 
 * @author qinglong
 * 
 */
class Consumer extends Thread {
	private Queue queue;

	Consumer(Queue queue) {
		this.queue = queue;
	}

	public void run() {
		while (true) {
			queue.consume();
			try {
				sleep(1000);
			} catch (Exception e) {
			}

		}
	}
}

/**
 * 消息类
 * 
 * @author qinglong
 * 
 */
class Message {
	public static int id;
	public String content;

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		Message.id = id;
	}
}